package com.cjm.one.common.config.redission;

import com.cjm.one.common.exception.GlobalException;
import com.cjm.one.common.result.Result;
import com.cjm.one.common.result.ResultCodeEnum;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

@Component
@RequiredArgsConstructor
public class DistributedLockTemplate {
    private final RedissonClient redissonClient;

    public <T> Result<T> execute(String lockKey, long waitTime, TimeUnit unit, Supplier<Result<T>> supplier) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            if (lock.tryLock(waitTime, unit)) {
                return supplier.get();
            }
            throw new GlobalException(ResultCodeEnum.SERVICE_UNAVAILABLE);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new GlobalException(ResultCodeEnum.LOCK_ERROR);
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}
